package com.zhuqieli.database_learn.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author dupr
 * @description ip拦截器实现
 * @date 2023/8/30 19:55:35
 */

@Component
public class IpInterceptor implements HandlerInterceptor {

    //ip和请求数map
    private final Map<String, Long> ipRequestCounts = new ConcurrentHashMap<>();
    //ip和上次请求时间map
    private final Map<String, Long> ipRequestWithLastRequest = new ConcurrentHashMap<>();
    private final long maxRequests = 20;
    private final long requestWindow = 10 * 1000;


    /**
     * ip拦截器
     *
     * @return 是否放过
     * @params HttpServletRequest request    HTTP请求
     * @params HttpServletResponse response  HTTP响应
     * @params Object handler                处理器
     * @author dupr
     * @date 2023/8/30 21:01:11
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //获取当前ip与访问时间
        String clientIp = getClientIp(request);
        long currentTime = System.currentTimeMillis();
        long lastRequestTime = ipRequestWithLastRequest.getOrDefault(clientIp, 0L);

        if (lastRequestTime + requestWindow < currentTime) {
            //间隔时间超过10秒则重新计数
            ipRequestWithLastRequest.put(clientIp, currentTime);
            ipRequestCounts.put(clientIp, 0L);
        } else {
            //记录请求次数
            long requestCount = ipRequestCounts.compute(clientIp, (key, value) -> (value == null) ? 1 : value + 1);
            if (requestCount > maxRequests) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                System.out.println("异常访问存在！ip地址:" + clientIp);
                return false;
            }
        }

        return true;
    }

    /**
     * 获取ip地址
     *
     * @return ip地址
     * @params HttpServletRequest request HTTP请求
     * @author dupr
     * @date 2023/8/30 21:02:47
     */
    private String getClientIp(HttpServletRequest request) {
        String clientIp = request.getHeader("X-Forwarded-For");
        if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
            clientIp = request.getHeader("Proxy-Client-IP");
        }
        if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
            clientIp = request.getHeader("WL-Proxy-Client-IP");
        }
        if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
            clientIp = request.getRemoteAddr();
        }
        return clientIp;
    }
}
